/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.ipccenter.toster.ejb;

import com.sun.xml.ws.api.tx.at.Transactional;
import edu.ipccenter.toster.*;
import edu.ipccenter.toster.jpa.*;
import java.math.BigInteger;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.List;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.Query;

/**
 *
 * @author 7
 */
@Stateful(name = "User")
@Transactional
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class UserBean implements User {

    @EJB
    SessionUtils session_utils;
    @EJB
    SuiteUtils suite_utils;
    @PersistenceContext(unitName = "TosterPU")
    private EntityManager em;
    private JPAUser user;
    private Session session;

    @Override
    public JPAUser getDatum() {
        return user;
    }

    @Override
    public void setDatum(JPAUser user) {
        this.user = user;
    }

    @Override
    public BigInteger getUserId() {
        if (user == null) {
            return null;
        }

        return user.getUserId();
    }

    @Override
    public String getUserName() {
        if (user == null) {
            return null;
        }
        return user.getUserName();
    }

    @Override
    public String getUserSurName() {
        if (user == null) {
            return null;
        }
        return user.getUserSurname();
    }

    @Override
    public void setUserName(String name) {
        if (user != null) {
            user.setUserName(name);
        }
    }

    @Override
    public void setUserSurName(String name) {

        if (user != null) {
            user.setUserSurname(name);
        }
    }

    @Override
    public Set<Name> getQuestionSet() {
        if (session == null) {
            return null;
        }
        Set<Name> question = new HashSet();

        Suite cur = session.getSuite();
        if (cur == null) {
            return null;
        }


        Iterator iter;

        JPATestSuite s = (JPATestSuite) cur.getSuite();
        Set<JPATestCase> quest = s.getTestcase();

        iter = quest.iterator();
        while (iter.hasNext()) {
            JPATestCase tc = (JPATestCase) iter.next();

            Name n = new Name();
            n.setID(tc.getTcId());
            n.setName(tc.getTcName());
            question.add(n);
        }
        //System.out.println("Suite:"+s.getSuiteId());




        return question;
    }

    //Returns all answers to user's suite questions
    @Override
    public Set<Answer> getAnswerSet() {
        if (session == null) {
            return null;
        }
        Set<Answer> ans = new HashSet();

        Suite su = session.getSuite();
        if (su == null) {
            return null;
        }
        Iterator iter;
        Iterator answ;

        JPATestSuite s = (JPATestSuite) su.getSuite();
        Set<JPATestCase> quest = s.getTestcase();

        iter = quest.iterator();
        while (iter.hasNext()) {
            JPATestCase tc = (JPATestCase) iter.next();

            answ = tc.getAnswers().iterator();
            while (answ.hasNext()) {
                JPAAnswer a = (JPAAnswer) answ.next();
                Answer ad = new Answer();
                ad.setID(a.getTcId());
                ad.setAnsNum(a.getAnsNum());
                ad.setContent(ad.getContent());
                if (a.getIscorrect() == 0) {
                    ad.setCorrectness(false);
                } else {
                    ad.setCorrectness(true);
                }
                ans.add(ad);
            }
        }


        return ans;
    }

    /*
     * @Override public void setPassedSuite(Suite suite) { Set<JPATestSuite>
     * test = user.getSuites();
     *
     *
     * if(suite.getSuite()!= null){ if(test.contains(suite.getSuite()))
     * System.out.println("Suite contains"); test.add(suite.getSuite());
     *
     * user.setSuites(test); em.merge(user);
     *
     * }
     * }
     *
     * @Override public void setPassedSuites(Set<Suite> suite) {
     * Set<JPATestSuite> test = user.getSuites();
     *
     * Iterator it = suite.iterator(); while(it.hasNext()){ Suite tc = (Suite)
     * it.next(); if(tc.getSuite()!=null) { if(test.contains(tc.getSuite()))
     * System.out.println("Suite contains"+tc);
     *
     * test.add(tc.getSuite()); } }
     *
     * user.setSuites(test); em.merge(user);
     *
     * }
     */
    @Override
    public Suite getRunTimeSuite() {
        Suite suite = null;

        Query q = em.createQuery("select c from JPASession c where c.user_id = :uid and c.end_date is null");
        q.setParameter("uid", getUserId());
        List l = q.getResultList();
        JPASession res = null;
        try {
            res = (JPASession) l.get(0);
        } catch (ArrayIndexOutOfBoundsException ex) {
            return null;
        }
        if (res == null) {
            return null;
        }
        if (res.getSuit_id() == null) {
            return null;
        }

        suite = suite_utils.findByID(res.getSuit_id());

        return suite;
    }

    @Override
    public void addAnswer(Answer ans) {
        if (session == null) {
            return;
        }
        if (session.getSuite() == null) {
            return;
        }
        System.out.println(ans);
        Set<JPATestCase> test_cases = session.getSuite().getSuite().getTestcase();
        if (test_cases == null) {
            return;
        }

        Iterator iter = test_cases.iterator();
        Iterator answ;
        while (iter.hasNext()) {
            JPATestCase tc = (JPATestCase) iter.next();
            answ = tc.getAnswers().iterator();
            while (answ.hasNext()) {
                JPAAnswer an = (JPAAnswer) answ.next();
                if (ans.getID().equals(an.getTcId())) {
                    session.setAnswer(ans);
                }

            }
        }




    }

    @Override
    public void startSuite(Suite suite) {
        if (session == null) {
            return;
        }
        session.setSuite(suite);
    }

    @Override
    public void endSuite() {
        if (session == null) {
            return;
        }
        session.closeSession();
    }

    @Override
    public Set<Session> getAllSessions() {
        if (user == null) {
            return null;
        }

        Set<Session> sessions = new HashSet<Session>();
        Query q = em.createQuery("select c from JPASession c where c.user_id = :id");
        q.setParameter("id", getUserId());

        List<JPASession> res = (List<JPASession>) q.getResultList();
        for (int i = 0; i < res.size(); i++) {
            sessions.add(session_utils.findById(res.get(i).getId()));
        }

        return sessions;
    }

    @Override
    public void setSession(Session session) {
        if (session == null) {
            return;
        }
        if (user == null) {
            return;
        }
        if (session.getUserId().equals(user.getUserId())) {
            this.session = session;
        }
    }

    @Override
    public Session getSession() {
        return session;
    }

    @Override
    public Set<Answer> getUserAnswers() {
        if (session == null) {
            return null;
        }
        return session.getUserAnswers();

    }

    @Override
    public Session getRunTimeSession() {
        Session ses = null;
        if (user == null) {
            return null;
        }
        if (session != null) {
            return session;
        }

        Query q = em.createQuery("select c from JPASession c where c.user_id = :id and c.end_date is null");
        q.setParameter("id", getUserId());

        try {
            JPASession jsession = (JPASession) q.getSingleResult();

            try {
                InitialContext ic = new InitialContext();
                ses = (Session) ic.lookup("java:global/Tost/Tost-ejb/Session");

            } catch (NamingException ex) {
                Logger.getLogger(SessionUtilsBean.class.getName()).log(Level.SEVERE, null, ex);
            }


            ses.setSessionData(jsession);
        } catch (Exception ex) {
            return null;
        }


        return ses;
    }
}
